home *** CD-ROM | disk | FTP | other *** search
/ Multimedia Jumpstart / Multimedia Microsoft Jumpstart Version 1.1a (Microsoft).BIN / develpmt / source / dialogs / color.c next >
Encoding:
C/C++ Source or Header  |  1992-06-02  |  13.1 KB  |  391 lines

  1. /*
  2.  * COLOR.C
  3.  *
  4.  * Code demonstrating the various uses of the ChooseColor common dialog.
  5.  *
  6.  * Copyright (c)1992 Microsoft Corporation, All Right Reserved
  7.  *
  8.  * Kraig Brockschmidt, Software Design Engineer
  9.  * Microsoft Systems Developer Relations
  10.  * One Microsoft Way
  11.  * Redmond, WA  98052
  12.  *
  13.  * Internet  :  kraigb@microsoft.com
  14.  * Compuserve:  70750,2344
  15.  * Fax       :  (206)936-7329
  16.  */
  17.  
  18. #include <windows.h>
  19. #include <commdlg.h>
  20. #include <dlgs.h>
  21. #include <colordlg.h>
  22. #include <memory.h>
  23. #include "dialogs.h"
  24.  
  25.  
  26.  
  27.  
  28. //Array of the standard 16 colors.
  29. DWORD rgColors16[16]={RGB(  0,   0, 0),       //Black
  30.                       RGB(128,   0, 0),       //Dark red
  31.                       RGB(  0, 128, 0),       //Dark green
  32.                       RGB(128, 128, 0),       //Dark yellow
  33.                       RGB(  0,   0, 128),     //Dark blue
  34.                       RGB(128,   0, 128),     //Dark purple
  35.                       RGB(  0, 128, 128),     //Dark aqua
  36.                       RGB(128, 128, 128),     //Dark grey
  37.                       RGB(192, 192, 192),     //Light grey
  38.                       RGB(255,   0, 0),       //Light red
  39.                       RGB(  0, 255, 0),       //Light green
  40.                       RGB(255, 255, 0),       //Light yellow
  41.                       RGB(  0,   0, 255),     //Light blue
  42.                       RGB(255,   0, 255),     //Light purple
  43.                       RGB(  0, 255, 255),     //Light aqua
  44.                       RGB(255, 255, 255),     //White
  45.                       };
  46.  
  47.  
  48.  
  49. /*
  50.  * ColorDialogs
  51.  *
  52.  * Purpose:
  53.  *  Invokes variations on the ChooseColor common dialog depending
  54.  *  on the menu selection.  Returns the chosen color to the caller.
  55.  *
  56.  * Parameters:
  57.  *  hWndOwner       HWND to use as the owner of the dialog.
  58.  *  iDialog         WORD indicating which dialog variation to invoke.
  59.  *
  60.  * Return Value:
  61.  *  COLORREF        Chosen color.  0xFFFFFFFF on error (an invalid color)
  62.  */
  63.  
  64. COLORREF PASCAL ColorDialogs(HWND hWndOwner, WORD iDialog)
  65.     {
  66.     static BOOL     fOpen=FALSE;
  67.     COLORREF        rgColors[16];
  68.     BOOL            fRet=FALSE;
  69.     HRSRC           hRes;
  70.     CHOOSECOLOR     cc;
  71.     UINT            i;
  72.  
  73.     /*
  74.      * Prevent reentrancy in cases where cc.hwndOwner==NULL or in our
  75.      * modeless case.  Any other situation is modal so we cannot be
  76.      * reentered anyway.
  77.      */
  78.     if (fOpen)
  79.         {
  80.         MessageBox(hWndOwner, "Color Dialog is already open", "ChooseColor", MB_OK);
  81.         return (COLORREF)0xFFFFFFFF;
  82.         }
  83.  
  84.  
  85.     /*
  86.      * The absolute minimum initialization before calling ChooseColor
  87.      * is to zero out the CHOOSECOLOR structure, set the lStructSize
  88.      * field, and set the lpCustColors field to point to an array of
  89.      * 16 COLORREFs.  lpCustColors cannot be NULL (ChooseColor will
  90.      * fail) and cannot be non-NULL but invalid (ChooseColor will
  91.      * repeatedly GP Fault).  Note that initializing the array of
  92.      * colors is not necessary.
  93.      */
  94.  
  95.     memset(&cc, 0, sizeof(CHOOSECOLOR));
  96.     cc.lStructSize=sizeof(CHOOSECOLOR);
  97.     cc.lpCustColors=rgColors;
  98.  
  99.  
  100.     /*
  101.      * Initialize colors to shades of blue.  This step is not absolutely
  102.      * necessary, but given the user something more than random colors.
  103.      */
  104.     if (IDM_COLORABSOLUTEMINIMUM!=iDialog)
  105.         {
  106.         for (i=0; i<16; i++)
  107.             rgColors[i]=RGB(0, 0, i*16);
  108.         }
  109.  
  110.  
  111.     switch (iDialog)
  112.         {
  113.         case IDM_COLORABSOLUTEMINIMUM:
  114.             /*
  115.              * When hWndOwner is not set, the dialog acts in a semi-modeless
  116.              * fashion; you can switch back to the parent window but you
  117.              * see little relationship between the dialog and the parent.
  118.              * For example, the parent can overlap this dialog.  Since it
  119.              * acts modeless, we use the fOpen flag to prevent reentrancy.
  120.              */
  121.             fOpen=TRUE;
  122.             fRet=ChooseColor(&cc);
  123.             fOpen=FALSE;
  124.             break;
  125.  
  126.  
  127.         case IDM_COLORBASIC:
  128.             /*
  129.              * In basic operation we initialize the custom colors as desired,
  130.              * give the dialog box an owner, and specify a default color in
  131.              * rgbResult.  In order to make that color in rgbResult show,
  132.              * set the CC_RGBINIT flag.
  133.              */
  134.             cc.hwndOwner=hWndOwner;
  135.             cc.rgbResult=RGB(0, 64, 0);
  136.             cc.Flags=CC_RGBINIT;
  137.             fRet=ChooseColor(&cc);
  138.             break;
  139.  
  140.  
  141.         case IDM_COLORFULLYOPEN:
  142.             //Same as the basic scenario but with CC_FULLOPEN
  143.             cc.hwndOwner=hWndOwner;
  144.             cc.rgbResult=RGB(64, 0, 0);
  145.             cc.Flags=CC_RGBINIT | CC_FULLOPEN;
  146.             fRet=ChooseColor(&cc);
  147.             break;
  148.  
  149.  
  150.         case IDM_COLORPREVENTOPEN:
  151.             //Same as the basic scenario but with CC_PREVENTFULLOPEN
  152.             cc.hwndOwner=hWndOwner;
  153.             cc.rgbResult=RGB(0, 0, 64);
  154.             cc.Flags=CC_RGBINIT | CC_PREVENTFULLOPEN;
  155.             fRet=ChooseColor(&cc);
  156.             break;
  157.  
  158.  
  159.         case IDM_COLORHOOKED:
  160.             /*
  161.              * Same as the basic scenario but with CC_SHOWHELP and
  162.              * CC_ENABLEHOOK.  We also have to initialize lpfnHook with a
  163.              * procedure instance address from MakeProcInstance. Help
  164.              * requests  will send the registered HELPMSGSTRING to the parent
  165.              * window procedure that can call WinHelp as necessary.  We could
  166.              * also process the WM_COMMAND message for the pshHelp control
  167.              * to spawn WinHelp, avoiding the registered message.
  168.              *
  169.              * The hook is simple--it only changes the title bar of the
  170.              * dialog--but for all common dialogs excep GetOpen/SavFileName
  171.              * a hook is the only way to change the title.
  172.              */
  173.             cc.hwndOwner=hWndOwner;
  174.             cc.rgbResult=RGB(0, 64, 0);
  175.  
  176.             //DLGHOOKPROC def'd in dialogs.h
  177.             cc.lpfnHook=(DLGHOOKPROC)MakeProcInstance(ColorHook, hgInst);
  178.  
  179.             cc.Flags=CC_RGBINIT | CC_SHOWHELP | CC_ENABLEHOOK;
  180.             fRet=ChooseColor(&cc);
  181.  
  182.             FreeProcInstance((FARPROC)cc.lpfnHook);
  183.             break;
  184.  
  185.  
  186.         case IDM_COLORCUSTOMIZEDTEMPLATE:
  187.             /*
  188.              * To customize the template we only have to provide an hInstance,
  189.              * the name of the template in our resources, and the
  190.              * CC_ENABLETEMPLATE flag. COMMDLG does the rest.
  191.              */
  192.             cc.hwndOwner=hWndOwner;
  193.             cc.rgbResult=RGB(0, 64, 0);
  194.             cc.hInstance=hgInst;
  195.             cc.Flags    =CC_ENABLETEMPLATE | CC_RGBINIT | CC_PREVENTFULLOPEN;
  196.  
  197.             //ChooseColor is the standard name of the dialog in COLOR.DLG
  198.             (LPCSTR)cc.lpTemplateName="ChooseColor";
  199.  
  200.             fRet=ChooseColor(&cc);
  201.             break;
  202.  
  203.  
  204.         case IDM_COLORCUSTOMIZEDUSINGHANDLE:
  205.             /*
  206.              * To customize using a handle to a dialog resource, we first
  207.              * find and load the resource, set it in hInstance, and set the
  208.              * CC_ENABLETEMPLATEHANDLE flag.  Using a handle is best when
  209.              * you're building a dialog template dynamically or otherwise
  210.              * do not have a named template that ChooseColor can just load
  211.              * from your resources.
  212.              *
  213.              * In the modeless version of this dialog, we have to use
  214.              * CC_FULLOPEN to allow the RGB edit controls to change with
  215.              * our color selection.  That way we can read the contents of
  216.              * those controls to get the current color to apply.
  217.              */
  218.             cc.lpCustColors=rgColors16;       //Standard 16 color array.
  219.             cc.rgbResult=RGB(255, 255, 255);
  220.             cc.Flags=CC_ENABLETEMPLATEHANDLE | CC_RGBINIT
  221.                      | CC_FULLOPEN | CC_ENABLEHOOK;
  222.  
  223.  
  224.             /*
  225.              * To create a modeless dialog, we do what er have before
  226.              * for setting up a hook.  However, we create an invisible
  227.              * popup window to serve as the owner which allows us to
  228.              * switch back to the main window.  The dialog is only modal
  229.              * for the popup window, and since that window is invisible,
  230.              * we appear as modeless to the real parent.  We still may need
  231.              * the parent window, so we pass that ti the hook in lCustData.
  232.              */
  233.             cc.lCustData=hWndOwner;
  234.             cc.hwndOwner=CreateWindow("ModelessPopup", "Parent"
  235.                       , WS_POPUP
  236.                       , 0, 0, 100, 100
  237.                       , hWndOwner, NULL, hgInst, NULL);
  238.  
  239.  
  240.             cc.lpfnHook=(DLGHOOKPROC)MakeProcInstance(ColorModelessHook, hgInst);
  241.  
  242.             //Locate and get a handle to the dialog resource.
  243.             hRes=FindResource(hgInst, "ChooseColor16", RT_DIALOG);
  244.             cc.hInstance=(HANDLE)LoadResource(hgInst, hRes);
  245.  
  246.             fOpen=TRUE;
  247.             fRet=ChooseColor(&cc);
  248.             fOpen=FALSE;
  249.  
  250.             //Be sure to clean up the handle from LoadResource.
  251.             FreeResource(cc.hInstance);
  252.             FreeProcInstance((FARPROC)cc.lpfnHook);
  253.             break;
  254.  
  255.  
  256.  
  257.         }
  258.  
  259.     if (!fRet)
  260.         cc.rgbResult=(COLORREF)0xFFFFFFFF;
  261.  
  262.     return cc.rgbResult;
  263.     }
  264.  
  265.  
  266.  
  267.  
  268.  
  269.  
  270. /*
  271.  * ColorHook
  272.  *
  273.  * Purpose:
  274.  *  Dialog procedure hook that simply changes the caption bar of the
  275.  *  dialog in the WM_INITDIALOG message case.  This is the only method
  276.  *  available to affect the caption bar in this and all other common
  277.  *  dialogs with the exception of GetOpen/SaveFileName.
  278.  *
  279.  *  For all messages except WM_INITDIALOG, the hook is called before
  280.  *  any default processing takes place.  For WM_INITDIALOG the hook
  281.  *  is called after the default procedure has done its thing.
  282.  *
  283.  * Parameters:
  284.  *  Standard parameter list for a dialog box procedure.
  285.  *
  286.  * Return Value:
  287.  *  UINT            Non-Zero or Zero, indicating if the common dialog should
  288.  *                  SKIP the message (non-zero) or not (zero).  Don't confuse
  289.  *                  with typical dialog box return values.
  290.  */
  291.  
  292. UINT FAR PASCAL ColorHook(HWND hDlg, UINT iMsg, UINT wParam, LONG lParam)
  293.     {
  294.     if (WM_INITDIALOG==iMsg)
  295.         {
  296.         SetWindowText(hDlg, "Select Window Background Color");
  297.         return TRUE;
  298.         }
  299.  
  300.     if (iMSGColorOK==iMsg)
  301.         {
  302.         /*
  303.          * The COLOROKSTRING message is sent on pressing OK.
  304.          * lParam points to the CHOOSECOLOR structure so you can
  305.          * validate the contents of all 16 colors in lpCustColors.
  306.          * If you accept them, return FALSE, otherwise return TRUE
  307.          * and the dialog will not close.
  308.          *
  309.          * Here we just notify the user of the message and let them
  310.          * choose to close or not.
  311.          */
  312.         wParam=MessageBox(hDlg
  313.                           , "COLOROKSTRING message received.\nClose Dialog?"
  314.                           , "ChooseColor", MB_YESNO);
  315.  
  316.         /*
  317.          * If we aren't closing the dialog, send the SETRGBSTRING message
  318.          * to select the default window background color, just for
  319.          * demonstration.
  320.          */
  321.         if (IDNO==wParam)
  322.             {
  323.             SendMessage(hDlg, iMSGSetRGB, 0, (LONG)GetSysColor(COLOR_WINDOW));
  324.             return TRUE;
  325.             }
  326.         }
  327.  
  328.     return FALSE;
  329.     }
  330.  
  331.  
  332.  
  333.  
  334. /*
  335.  * ColorModelessHook
  336.  *
  337.  * Purpose:
  338.  *  ChooseColor hook procedure that overrides the OK button to mean
  339.  *  Apply, retriveing the current color selection from the RGB values
  340.  *  in the COLOR_RED, COLOR_GREEN, and COLOR_BLUE controls that are
  341.  *  in the dialog and updated, but hidden.
  342.  *
  343.  * Parameters:
  344.  *  Standard parameter list for a dialog box procedure.
  345.  *
  346.  * Return Value:
  347.  *  See ColorHook above.
  348.  */
  349.  
  350. UINT FAR PASCAL ColorModelessHook(HWND hDlg, UINT iMsg, UINT wParam, LONG lParam)
  351.     {
  352.     static HWND hWndParent;
  353.     UINT        r, g, b;
  354.     BOOL        fTemp;
  355.     RECT        rc;
  356.     POINT       pt;
  357.  
  358.     if (WM_INITDIALOG==iMsg)
  359.         {
  360.         //Button text already changed in the template.  So just save the real parent.
  361.         hWndParent=(HWND)((LPCHOOSECOLOR)lParam)->lCustData;
  362.  
  363.         //Reposition the window relative to the hWndParent
  364.         pt.x=0;
  365.         pt.y=0;
  366.         ClientToScreen(hWndParent, &pt);
  367.         GetWindowRect(hDlg, &rc);
  368.  
  369.         SetWindowPos(hDlg, NULL, pt.x+rc.left, pt.y+rc.top
  370.                      , 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
  371.         return TRUE;
  372.         }
  373.  
  374.  
  375.     if (WM_COMMAND==iMsg && IDOK==LOWORD(wParam))
  376.         {
  377.         //Get the current RGB values from the hidden, but active, edit controls.
  378.         r=GetDlgItemInt(hDlg, COLOR_RED, &fTemp, FALSE);
  379.         g=GetDlgItemInt(hDlg, COLOR_GREEN, &fTemp, FALSE);
  380.         b=GetDlgItemInt(hDlg, COLOR_BLUE, &fTemp, FALSE);
  381.  
  382.         //Inform our main window that the color changed.
  383.         SendMessage(hWndParent, USER_CHANGECOLOR, 0, RGB(r,g,b));
  384.  
  385.         //Tell the default procedure to skip this message.
  386.         return TRUE;
  387.         }
  388.  
  389.     return FALSE;
  390.     }
  391.